home *** CD-ROM | disk | FTP | other *** search
- Path: mail2news.demon.co.uk!genesis.demon.co.uk
- From: Lawrence Kirby <fred@genesis.demon.co.uk>
- Newsgroups: comp.lang.c
- Subject: Re: How to get a random strin
- Date: Tue, 27 Feb 96 00:04:01 GMT
- Organization: none
- Message-ID: <825379441snz@genesis.demon.co.uk>
- References: <4g19id$p7n@gail.ripco.com> <Dn5E0J.GKL@thinkage.on.ca> <4gqir9$d5r@airdmhor.gen.nz>
- Reply-To: fred@genesis.demon.co.uk
- X-NNTP-Posting-Host: genesis.demon.co.uk
- X-Newsreader: Demon Internet Simple News v1.27
- X-Mail2News-Path: genesis.demon.co.uk
-
- In article <4gqir9$d5r@airdmhor.gen.nz>
- gumboot@airdmhor.gen.nz "Simon Hosie" writes:
-
- >In article <4g19id$p7n@gail.ripco.com> mambuhl@ripco.com (Martin Ambuhl)
- > writes:
- >> chancl@nevada.edu (Clapton Chan) in <4fh5od$qq0@news.nevada.edu> asks:
- >>
- >> [A poor practice follows]
- >> if you do not #include <time.h>, you need
- >> srand((unsigned)time(NULL));
- >
- >Alan Bowler:
- >> Worse than poor. time() returns a time_t which might not be an
- >> integer type. The above code implicitly declares "time()" as returning
- >> int. Adding the cast to unsigned will not change that fact that
- >> this implicit declaration means your code could be looking in the
- >> wrong place. For example: Suppose "time_t" is actually "double"
- >> and not "int", and that the machine uses has separate floating
- >> point and integer registers. (x86, pdp-11, ibm/370). Then the
- >> above code could well result in the same vale being passed to srand()
- >> every time the program is called, because time() set the floating
- >> point result register and the above code is looking at an integer
- >> result register which untouched by time().
- >
- > I don't follow that.. if time returns a float then won't the result be
- >cast and truncated to an int?
-
- Only if the compiler knows that time() returns float. The only way it
- can know is if there is a declaration of time() in scope (e.g. from
- including time.h). Without that the compiler must assume that time()
- returns int hence will generate the code required (whixh may be none) to
- convert int to unsigned, *not* float to unsigned.
-
- With an appropriate declaration this will work if the truncated value is
- representable as an unsigned int. If not the result is undefined behaviour.
- On most systems floats can represent much larger values than ints.
-
- While integer operations where the result is unsigned cannot overflow
- (and produce undefined behaviour) floating point -> unsigned conversions
- *can*.
-
- >Is the following legal, by the way?
- >
- > char Temp[sizeof(time_t) + sizeof(unsigned)];
- >
- > time((time_t *)Temp);
- > srand(*(unsigned *)Temp);
-
- There is no guarantee that Temp is aligned suitably for either a time_t or
- an unsigned. You could overcome that using malloc.
-
- There is no guarantee that time_t is as long as unsigned. This means that
- not all bytes of *(unsigned *)Temp may be set.
-
- C doesn't guarantee that accessing an object via an unsigned lvalue will
- be aliased to accessing it via a time_t lvalue.
-
- What you can do is something like:
-
- {
- time_t timeval = time(NULL);
- unsigned char *ptr = (unsigned char *)&timeval;
- unsigned seed = 0;
- int i;
-
- for (i = 0; i < sizeof timeval; i++)
- seed = (seed + ptr[i]) * N;
-
- srand(seed);
- }
-
- where N can be chosen to 'diffuse' small changes in timeval throughout
- the seed. It should be at least odd so that lower order bits are affected.
- Making it prime may or may not produce any benefit but it shouldn't do
- any harm.
-
- --
- -----------------------------------------
- Lawrence Kirby | fred@genesis.demon.co.uk
- Wilts, England | 70734.126@compuserve.com
- -----------------------------------------
-